package control;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

import view.ViewWindow;

/**
 * Controlador da interface gráfica. Instancia o objeto da janela,
 * <code>ViewWindow</code>, bem como o controlador dos autômatos,
 * <code>ControllerLexicAnalyzer</code>. Faz o tratamento de eventos
 * de acordo com a utilização do usuário e, em momento oportuno,
 * passa o controle à <code>ControllerLexicAnalyzer</code>, para que
 * seja iniciado o processo de reconhecimento de tokens.
 * 
 * @author 	Jody Matos, Alenilson
 * @version 1.3
 * @since	10/18/2011
 * 
 * <dt><b>History:</b></dt>
 * 	<dd>1.0: Creation of first methods</dd>
 *  <dd>1.1: Update of overall methods adapting him to our project instead auto-generated 
 *  	code)</dd>
 * 	<dd>1.2: Implementation of actionPerformed for the Open and Exit events</dd>
 *  <dd>1.3: Reading  a File and showing it on the main window</dd>
 */
public class ControllerWindow implements ActionListener{
	private ControllerLexicAnalyzer	lexicAnalyzer;
	private ControllerParser		parser;
	private ViewWindow 				window;
	private String					path;
	
	/**
	 * Cria uma instância de <code>ControllerWindow</code>, já instanciando e exibindo a janela
	 * de interface com o usuário, <code>VewWindow</code>.
	 */
	public ControllerWindow() {
		lexicAnalyzer = new ControllerLexicAnalyzer();
		window = new ViewWindow(this);
		window.setVisible(true);
	}

	/**
	 * Gestor de eventos da janela de interface. De acordo com o objeto que gerou o evento,
	 * faz o tratamento devido.
	 */
	public void actionPerformed(ActionEvent event) {
		if((event.getSource()==window.getOpenButton())||(event.getSource()==window.getOpenMenu())){
			path = new String();
			path = this.fileChooser();
			System.out.println("Caminho="+path);
			File source = new File(path);
			lexicAnalyzer.setSource(source);
			String sourceCode = lexicAnalyzer.getSourceCode();
			this.setSourceCode(sourceCode);
		}
		else if(event.getSource()==window.getCompileButton()){
			lexicAnalyzer.scan();
			System.out.println("Erros Léxicos:"+lexicAnalyzer.getErrors().size());
			parser = new ControllerParser(lexicAnalyzer.getTokens(), lexicAnalyzer.getErrors());
			if(lexicAnalyzer.getErrors().isEmpty()) parser.parse();
			window.setTokens(lexicAnalyzer.getTokens());
			//System.out.println("Erros Sintáticos:"+parser.getErrors().size());
			window.setErrors(parser.getErrors());
		}
		else if (event.getSource()==window.getExitMenu()){
			System.exit(0);
		}
	}

	/**
	 * Utilizado na gestão do evento de abrir o código-fonte, esse método
	 * modulariza o processo de exibição e tratamento de um <code>JFileChooser</code>,
	 * retornando uma <code>String</code> com o caminho completo do arquivo selecioando.
	 * 
	 * @return <code>String</code> com o caminho do arquivo-fonte.
	 */
	private String fileChooser(){
		String caminho = null;  
	    
        JFileChooser arquivo = new JFileChooser(".");  
    
        arquivo.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        arquivo.setFileFilter(new FileFilter() {
			
				
			@Override
			public boolean accept(File arg0) {
				if (arg0.isDirectory()) {
					return true;
				    }

				    if (arg0.getName().endsWith(".txt")) {
					        return true;
					} else {
					    return false;
					}
			}

			@Override
			public String getDescription() {
				return null;
			}
		});
        
        int resposta = arquivo.showOpenDialog(null);  
        if (resposta == JFileChooser.APPROVE_OPTION) {  
          caminho = arquivo.getSelectedFile().getPath();  
        } else {  
          System.out.print("Execução cancelada.");
        }
        return caminho;
	}
	
	public String getPath(){
		return this.path;
	}
	
	/**
	 * Informa ao objeto de interface com o usuário a <code>String</code>
	 * completa com o conteúdo do código-fonte, para que seja exibido no
	 * campo específico.
	 * 
	 * @param sourceCode Conteúdo do código-fonte a ser exibido ao usuário.
	 */
	private void setSourceCode(String sourceCode){
		window.setSourceCode(sourceCode);
		window.validate();
		window.repaintFrame();
	}
}